package com.open.capacity.user.service.impl;

import com.open.capacity.commons.Result;
import com.open.capacity.reimburse.util.uuid.UUIDUtils;
import com.open.capacity.user.dao.SysPostDao;
import com.open.capacity.user.model.SysPost;
import com.open.capacity.user.service.SysPostService;
import com.open.capacity.user.vo.SysPostExcel;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
public class SysPostServiceImpl implements SysPostService {

    @Autowired
    private SysPostDao postDao;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysPost sysPost) {
        SysPost post = postDao.findByCode(sysPost.getCompanyId(), sysPost.getDepartmentId(), sysPost.getCode());
        if (post != null) {
            throw new IllegalArgumentException("岗位code已存在");
        }
        sysPost.setCreateTime(new Date());
        sysPost.setUpdateTime(sysPost.getCreateTime());

        if (sysPost.getIsDefault() != null && sysPost.getIsDefault().equals(1)) {
            Map<String, Object> params = new HashMap<>();
            params.put("companyId", sysPost.getCompanyId());
            params.put("status", 1);
            List<SysPost> list = postDao.findList(params);
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(item -> {
                    item.setIsDefault(0);
                    postDao.updateDefault(item);
                });
            }
        }

        postDao.updateByOps(sysPost);

        postDao.save(sysPost);
        log.info("保存岗位：{}", sysPost);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SysPost sysPost) {
        sysPost.setUpdateTime(new Date());

        if (sysPost.getIsDefault() != null && sysPost.getIsDefault().equals(1)) {
            Map<String, Object> params = new HashMap<>();
            params.put("companyId", sysPost.getCompanyId());
            params.put("status", 1);
            List<SysPost> list = postDao.findList(params);
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(item -> {
                    item.setIsDefault(0);
                    postDao.updateDefault(item);
                });
            }
        }

        postDao.updateByOps(sysPost);

        log.info("修改岗位：{}", sysPost);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        SysPost sysPost = postDao.findById(id);

        postDao.delete(id);

        log.info("删除岗位：{}", sysPost);
    }


    @Override
    public SysPost findById(String id) {
        return postDao.findById(id);
    }

    @Override
    public SysPost findDefault(String companyId) {
        return postDao.findDefault(companyId);
    }

    @Override
    public List<SysPost> findPosts(Map<String, Object> params) {
        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
//        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
//            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);
        List<SysPost> list = postDao.findList(params);

        return list;
    }

    @Override
    public List<SysPost> findByParentId(String parentId) {
        return postDao.findByParentId(parentId);
    }


    @Override
    public Result saveOrUpdate(SysPost sysPost, String keyValue) {
        int i = 0;

        if (sysPost.getIsDefault() != null && sysPost.getIsDefault().equals(1)) {
            Map<String, Object> params = new HashMap<>();
            params.put("companyId", sysPost.getCompanyId());
            params.put("status", 1);
            List<SysPost> list = postDao.findList(params);
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(item -> {
                    item.setIsDefault(0);
                    postDao.updateDefault(item);
                });
            }
        }

        if (StringUtils.isNotEmpty(keyValue)) {
            SysPost model = postDao.findById(keyValue);
            if (model != null) {
                sysPost.setId(keyValue);
                sysPost.setUpdateTime(new Date());
                i = postDao.updateByOps(sysPost);
            }
        } else {
            SysPost post = postDao.findByCode(sysPost.getCompanyId(), sysPost.getDepartmentId(), sysPost.getCode());
            if (post != null) {
                throw new IllegalArgumentException("岗位code已存在");
            }
            sysPost.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            sysPost.setCreateTime(new Date());
            sysPost.setUpdateTime(sysPost.getCreateTime());
            i = postDao.save(sysPost);
        }

        return i > 0 ? Result.succeed("操作成功") : Result.failed("操作失败");
    }


    @Override
    public List<SysPostExcel> findExcels(Map<String, Object> params) {
        List<SysPost> list = postDao.findList(params);
        List<SysPostExcel> result = new ArrayList<>();
        for (SysPost post : list) {
            SysPostExcel excel = new SysPostExcel();
            BeanUtils.copyProperties(post, excel);
            result.add(excel);
        }
        return result;
    }

    @Override
    public Boolean isUp(List<String> myId, List<String> otherId) {
        boolean res = false;
        if (CollectionUtils.isNotEmpty(myId) && CollectionUtils.isNotEmpty(otherId)) {
            String[] myList = (String[]) myId.toArray();
            String[] array = (String[]) myId.toArray();
            Map<String, Integer> map = new HashMap<>();
            String[] array2 = array;
            for (String otherItem : array2) {
                if (!map.containsKey(otherItem)) {
                    map.put(otherItem, 1);
                }
            }
            array2 = myList;
            for (String myItem : array2) {
                if (hasRelation(myItem, map)) {
                    res = true;
                    break;
                }
            }
        }
        return res;
    }

    @Override
    public Boolean isDown(List<String> myId, List<String> otherId) {
        boolean res = false;
        if (CollectionUtils.isNotEmpty(myId) && CollectionUtils.isNotEmpty(otherId)) {
            String[] myList = (String[]) myId.toArray();
            String[] otherList = (String[]) myId.toArray();
            Map<String, Integer> map = new HashMap<>();
            String[] array = myList;
            for (String myItem : array) {
                if (!map.containsKey(myItem)) {
                    map.put(myItem, 1);
                }
            }
            array = otherList;
            for (String otherItem : array) {
                if (hasRelation(otherItem, map)) {
                    res = true;
                    break;
                }
            }
        }
        return res;
    }

    public List<String> getUpIdList(List<String> strPostIds, Integer level) {
        List<String> res = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(strPostIds) && level > 0 && level < 6) {
            String[] array = (String[]) strPostIds.toArray();
            boolean isHave = false;
            String[] array2 = array;
            for (String postId : array2) {
                isHave = false;
                SysPost entity = postDao.findById(postId);
                if (entity == null) {
                    continue;
                }
                String parentId = entity.getParentId();
                SysPost parentEntity = null;
                for (int i = 0; i < level; i++) {
                    parentEntity = postDao.findById(parentId);
                    if (parentEntity == null) {
                        break;
                    }
                    parentId = parentEntity.getParentId();
                    if (i == level - 1) {
                        isHave = true;
                    }
                }
                if (isHave && parentEntity != null) {
                    res.add(parentEntity.getId());
                }
            }
        }
        return res;
    }

    public List<String> getDownIdList(List<String> strPostIds, int level) {
        List<String> res = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(strPostIds) && level > 0 && level < 6) {
            String[] postIdList = (String[]) strPostIds.toArray();
            boolean isHave = false;
            List<String> parentList = new ArrayList<>();
            parentList.addAll(Arrays.asList(postIdList));
            for (int i = 0; i < level; i++) {
                for (String parentId : parentList) {
                    List<SysPost> byParentId = postDao.findByParentId(parentId);
                    if (CollectionUtils.isNotEmpty(byParentId)) {
                        parentList.addAll(byParentId.stream().map(SysPost::getId).collect(Collectors.toList()));
                    }
                }
                if (parentList.size() <= 0) {
                    break;
                }
                if (i == level - 1) {
                    isHave = true;
                }
            }
            if (isHave) {
                res.addAll(parentList);
            }
        }
        return res;
    }

    private boolean hasRelation(String beginId, Map<String, Integer> map) {
        boolean res = false;
        SysPost entity = postDao.findById(beginId);
        if (entity == null || entity.getParentId().equals("0")) {
            return false;
        }
        if (map.containsKey(entity.getParentId())) {
            return true;
        }
        return hasRelation(entity.getParentId(), map);
    }
}
